import 'dart:io';
import 'dart:math';

import 'package:audioplayers/audioplayers.dart';
import 'package:desktop_screenshot/desktop_screenshot.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';

import 'package:hotkey_manager/hotkey_manager.dart';
import 'package:flutter/services.dart';
import 'package:image/image.dart' as Img;
import 'package:test2/base/base_page.dart';
import 'package:test2/model/map.dart';
import 'package:test2/util/bus.dart';
import 'package:test2/widget/image.dart';

import '../util/PicUtil.dart';
import '../util/platform.dart';

class MapAdd extends StatefulWidget {
  const MapAdd({super.key, this.info, required this.boxName});

  final String boxName;
  final MapC? info;

  @override
  State<MapAdd> createState() => _MapAddState();
}

class _MapAddState extends BaseState<MapAdd> {
  final _desktopScreenshotPlugin = DesktopScreenshot();
  AudioPlayer audioPlayer = AudioPlayer();

  Uint8List? screenshot;

  bool edit = false;
  late MapC info;
  File? selectPic;
  bool picChanged = false;
  TextEditingController _textEditingController = TextEditingController();
  HotKey _hotKey = HotKey(
    key: PhysicalKeyboardKey.keyQ,
    modifiers: [HotKeyModifier.alt],
    scope: HotKeyScope.system,
  );

  initHotkey() async {
    if (!PlatformUtil.isDesktop()) {
      return;
    }

    await hotKeyManager.register(
      _hotKey,
      keyDownHandler: (hotKey) {
        // print('onKeyDown+${hotKey.toJson()}');
        takeScreenshot();
      },
    );
  }

  Future<void> takeScreenshot() async {
    if (!edit) {
      return;
    }
    Uint8List? screenShot;
    try {
      screenShot = await _desktopScreenshotPlugin.getScreenshot();
      await audioPlayer.stop();
      audioPlayer.play(AssetSource("mp3/ss.mp3"));
      picChanged = true;
    } on PlatformException catch (e) {
      print('Failed to capture screenshot: ${e.message}');
    }

    if (kDebugMode) {
      print("ScreenShotSize ${screenShot?.lengthInBytes}");
    }

    if (!mounted) return;

    setState(() {
      if (screenShot != null) {
        var decodeImage2 = Img.decodeImage(screenShot!);
        if (decodeImage2 != null) {
          double scaleW = decodeImage2.width / 1920;
          double scaleH = decodeImage2.height / 1080;
          double scale = min(scaleW, scaleH);
          if (scale < 1) {
            scale = 1;
          }

          decodeImage2 = Img.resize(
            decodeImage2,
            width: (decodeImage2.width / scale).toInt(),
            height: (decodeImage2.height / scale).toInt(),
            maintainAspect: true,
          );
          screenShot = Img.encodePng(decodeImage2);
        }

        screenshot = screenShot;
        selectPic = null;
      }
    });
  }

  @override
  void initState() {
    if (widget.info == null) {
      info = MapC(tip: "", pic: "", top: false);
      edit = true;
    } else {
      info = MapC(
        tip: widget.info!.tip,
        pic: widget.info!.pic,
        top: widget.info!.top,
      );
    }
    _textEditingController.text = info.tip;
    if (widget.info?.key != null) {
      selectPic = File(PicUtil.picRootPath + info.pic);
    }

    initHotkey();
    super.initState();
  }

  @override
  void dispose() {
    if (PlatformUtil.isDesktop()) {
      hotKeyManager.unregister(_hotKey);
    }

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.info?.key == null ? "添加地图" : "修改地图"),
        actions: [
          if (!edit)
            IconButton(
              onPressed: () {
                setState(() {
                  edit = true;
                });
              },
              icon: Icon(Icons.edit),
            ),
        ],
      ),
      floatingActionButton: edit
          ? FloatingActionButton(
              onPressed: () {
                commit();
              },
              child: Icon(Icons.check),
            )
          : null,
      body: SizedBox.expand(
        child: SingleChildScrollView(
          padding: EdgeInsets.all(16),
          child: Column(
            spacing: 20,
            children: [
              TextField(
                readOnly: !edit,
                controller: _textEditingController,
                decoration: InputDecoration(labelText: "地图名"),
                onChanged: (s) {
                  info.tip = s;
                },
              ),

              Text(
                "tip: 按下快捷键可直接截取屏幕",
                style: TextStyle(fontSize: 12, color: Color(0xff999999)),
              ),

              ImagePickView(
                enable: edit,
                showScreenshot: false,
                imageProvider: getImgProvider(selectPic, screenshot),
                title: "封面",
                onPick: (file) {
                  setState(() {
                    selectPic = file;
                    screenshot = null;

                    picChanged = true;
                  });
                },
              ),
            ],
          ),
        ),
      ),
    );
  }

  ImageProvider? getImgProvider(File? file, Uint8List? screenshot) {
    if (file != null && screenshot != null) {
      throw Exception("file && screenshot exist!");
    }

    if (file != null) {
      return FileImage(file);
    }
    if (screenshot != null) {
      return MemoryImage(screenshot);
    }

    return null;
  }

  void commit() async {
    if (info.tip.isEmpty) {
      showToast("请输入地图名");
      return;
    }
    if (selectPic == null && screenshot == null) {
      showToast("请选择图片");
      return;
    }

    // 修改图片要删除旧的

    if (picChanged) {
      // 删除旧图片
      if (widget.info?.key != null) {
        info.deletePic();
      }

      print("save");
      String picName = PicUtil.savePic(
        selectPic == null ? screenshot : selectPic!.readAsBytesSync(),
      );
      if (picName.isEmpty) {
        showToast("图片保存出错");
        return;
      }

      info.pic = picName;
    }

    if (widget.info?.key == null) {
      Hive.box<MapC>(widget.boxName).add(info);
    } else {
      Hive.box<MapC>(widget.boxName).put(widget.info?.key, info);
    }

    bus.emit(EventType.map);

    finish();
  }
}
